#pragma once

#include<iostream>
#include<arpa/inet.h>
#include<netinet/in.h>
#include<sys/socket.h>
#include<sys/types.h>
#include<string.h>

#include"Log.hpp"
#include"InetAddr.hpp"

class Server
{
public:
    Server(uint16_t port)
    :_port(port),
    _is_runing(false)
    {
        _sockfd=socket(AF_INET,SOCK_DGRAM,0);
        if(socket<0)
        {
            Log(FATAL,"server creates sockfd error\n");
            exit(-1);
        }
        Log(DEBUG,"server creates sockfd %d successfully\n",_sockfd);

        sockaddr_in addr;
        bzero(&addr,sizeof(addr));
        addr.sin_family=AF_INET;
        addr.sin_port=_port;
        addr.sin_addr.s_addr=INADDR_ANY;
        //addr.sin_addr.s_addr=inet_addr("120.25.125.132");

        if(0<bind(_sockfd,(struct sockaddr*)(&addr),sizeof(addr)))
        {
            Log(FATAL,"server binds  error\n");
            exit(-1);
        }
        Log(DEBUG,"server binds successfully\n");
    }

    void Start()
    {
        _is_runing=true;
        Log(DEBUG,"Server launches scessfully\n");
        while(_is_runing)
        {
            struct sockaddr_in client_addr;
            bzero(&client_addr,sizeof(client_addr));
            socklen_t len=sizeof(client_addr);
            char buf[1024];
            int rn=recvfrom(_sockfd,buf,sizeof(buf),0,(struct sockaddr*)(&client_addr),&len);
            if(rn<0)
            {
                Log(ERROR,"server reads error\n");
                return;
            }
            buf[rn]=0;
            InetAddr addr(client_addr);
            Log(DEBUG,"Server read sucessfully form id %s port %d,message:%s\n",addr.Ip().c_str(),addr.Port(),buf);

            int wn=sendto(_sockfd,buf,sizeof(buf),0,(struct sockaddr*)(&client_addr),sizeof(client_addr));
            if(wn<0)
            {
                Log(ERROR,"server writes error\n");
                return;
            }
            Log(ERROR,"server writes sucessfully\n");

            sleep(1);
        }
        Log(DEBUG,"Server quit scessfully\n");
    }

    ~Server()
    {}

private:
    uint16_t _port;
    int _sockfd;
    bool _is_runing;
};